﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Configuration;

namespace DirectoryUpdate
{
    public partial class DirectorySync : Form
    {
        private int UpdatedFiles = 0;

        public DirectorySync()
        {
            InitializeComponent();
        }

        private void OpenSourceButton_Click(object sender, EventArgs e)
        {
            SelectFolder(SourceTextBox);
        }

        private void OpenTargetButton_Click(object sender, EventArgs e)
        {
            SelectFolder(TargetTextBox);
        }

        private void SelectFolder(TextBox dir)
        {
            DialogResult res = folderBrowserDialog.ShowDialog();
            if (res == DialogResult.OK)
            {
                dir.Text = folderBrowserDialog.SelectedPath;
            }

        }

        private void SyncButton_Click(object sender, EventArgs e)
        {
            try
            {
                LogListBox.Items.Clear();
                DirectoryInfo sourceFolder = new DirectoryInfo(SourceTextBox.Text);
                DirectoryInfo targetFolder = new DirectoryInfo(TargetTextBox.Text);
                if (!sourceFolder.Exists || !targetFolder.Exists)
                {
                    MessageBox.Show("Invalid Source or Target folder(s)");
                }
                else
                {
                    string warningMessage = "This operation can take several minutes, depending the quantity of files to be synchronized";
                    DialogResult result = MessageBox.Show(warningMessage, "Warning.\n Do you want to continue?", MessageBoxButtons.YesNo);
                    if (result == DialogResult.No) {
                        return;
                    }
                    BackgroundWorker.RunWorkerAsync();
                }
            } catch (Exception ex) {
                MessageBox.Show("ERROR: " + ex.Message);
            }
        }

        private delegate void AddListBoxItemDelegate(object item);

        private void UpdateLog(object item)
        {
            if (this.LogListBox.InvokeRequired)
            {
                // This is a worker thread so delegate the task.
                this.LogListBox.Invoke(new AddListBoxItemDelegate(this.UpdateLog), item);
            }
            else
            {
                // This is the UI thread so perform the task.
                this.LogListBox.Items.Add(item);
                LogListBox.SelectedIndex = LogListBox.Items.Count - 1;
            }
        }

        private void SynchronizeFolder(DirectoryInfo sourceFolder, DirectoryInfo targetFolder) {
            FileInfo[] files = sourceFolder.GetFiles();
            foreach (FileInfo file in files)
            {
                if (file.Attributes == FileAttributes.System)
                {
                    continue;
                }
                string sourceAux = file.FullName.Replace(SourceTextBox.Text, "");
                string targetAux = TargetTextBox.Text + sourceAux;
                string targetFolderToBeCreated = targetAux.Substring(0, targetAux.LastIndexOf("\\"));
                if (!Directory.Exists(targetFolderToBeCreated)) {
                    Directory.CreateDirectory(targetFolderToBeCreated);
                }
                if (file.LastWriteTime.CompareTo(File.GetLastWriteTime(targetAux)) != 0)
                {
                    file.CopyTo(targetAux, true);
                    UpdatedFiles++;

                    string newLogItem = UpdatedFiles.ToString().PadLeft(6, ' ') +
                                        " => " + targetAux;

                    UpdateLog(newLogItem);
                }                
            }
            foreach (DirectoryInfo folder in sourceFolder.GetDirectories())
            {
                if (folder.Attributes != FileAttributes.System)
                {
                    SynchronizeFolder(folder, targetFolder);
                }                
            }
        }

        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            SynchronizeFolder(new DirectoryInfo(SourceTextBox.Text), new DirectoryInfo(TargetTextBox.Text));
            Properties.Settings.Default.SOURCE_FOLDER = SourceTextBox.Text;
            Properties.Settings.Default.TARGET_FOLDER = TargetTextBox.Text;
            Properties.Settings.Default.Save();
            MessageBox.Show(string.Format("Folders synchronized!\n {0} files copied!", UpdatedFiles));
            UpdatedFiles = 0;
        }
    }
}